<template>
  <div class="app-container">
    <div class="action-container"><el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">添加菜单</el-button></div>
    <el-table v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row default-expand-all>
      <el-table-column prop="id" label="菜单ID" align="center" width="150" />
      <el-table-column prop="title" label="菜单名称" width="180" />
      <el-table-column prop="icon" label="icon" />
      <el-table-column prop="path" label="路由路径" />
      <el-table-column prop="name" label="路由名称" />
      <el-table-column prop="redirect" label="路由重定向" />
      <el-table-column prop="hidden" label="侧边栏">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.hidden"
            active-color="#13ce66"
            :active-value="0"
            :inactive-value="1"
            inactive-color="#ff4949"
            active-text="显示"
            inactive-text="隐藏"
            @change="handleSwitch(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="breadcrumb" label="面包屑">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.breadcrumb"
            active-color="#13ce66"
            :active-value="1"
            :inactive-value="0"
            inactive-color="#ff4949"
            active-text="显示"
            inactive-text="隐藏"
            @change="handleSwitch(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="sort" label="排序" />
      <el-table-column label="操作" align="center" width="240" class-name="small-padding fixed-width">
        <template slot-scope="{ row }">
          <el-button type="primary" size="mini" @click="handleUpdate(row)">编辑</el-button>
          <el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog :title="dialogTitleMap[dialogStatus]" :close-on-click-modal="false" :visible.sync="dialogFormVisible">
      <el-form ref="dataForm" class="dataForm" :rules="rules" :model="temp" label-position="left" label-width="85px" style="width: 400px; margin-left:50px;">
        <el-form-item label="菜单名称" prop="title"><el-input v-model="temp.title" maxlength="30" placeholder="请输入菜单名称" /></el-form-item>
        <el-form-item label="父级菜单" prop="pid">
          <el-cascader v-model="temp.pid" :options="list" filterable clearable :props="{ label: 'title', value: 'id', checkStrictly: true, emitPath: false }" />
        </el-form-item>
        <el-form-item label="侧边栏显示" prop="hidden">
          <el-switch v-model="temp.hidden" active-color="#13ce66" :active-value="0" :inactive-value="1" inactive-color="#ff4949" active-text="显示" inactive-text="隐藏" />
        </el-form-item>
        <el-form-item label="面包屑显示" prop="breadcrumb">
          <el-switch v-model="temp.breadcrumb" active-color="#13ce66" :active-value="1" :inactive-value="0" inactive-color="#ff4949" active-text="显示" inactive-text="隐藏" />
        </el-form-item>
        <el-form-item label="icon" prop="icon">
          <el-input v-model="temp.icon" placeholder="请输入内容">
            <template slot="append">
              <span class="select-icon-btn" @click="dialogIconVisible = true">选择图标</span>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="授权角色" prop="roles">
          <el-select v-model="temp.roles" multiple filterable placeholder="请授权角色">
            <el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item label="路由路径" prop="path"><el-input v-model="temp.path" maxlength="30" placeholder="请输入前端的路由路径" /></el-form-item>
        <el-form-item label="路由名称" prop="name"><el-input v-model="temp.name" maxlength="30" placeholder="请输入前端的路由名称" /></el-form-item>
        <el-form-item label="路由重定向" prop="redirect"><el-input v-model="temp.redirect" maxlength="30" placeholder="请输入前端的路由重定向" /></el-form-item>
        <el-form-item label="排序" prop="sort"><el-input v-model="temp.sort" maxlength="30" placeholder="请输入排序,菜单会根据排序值从小到大排列" /></el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="dialogStatus === 'create' ? createData() : updateData()">提交</el-button>
      </div>
    </el-dialog>

    <el-dialog class="iconDialog" title="选择icon" :close-on-click-modal="false" :visible.sync="dialogIconVisible">
      <el-tabs type="border-card">
        <el-tab-pane label="Icons">
          <div class="grid">
            <div v-for="item of svgIcons" :key="item" @click="handleCheckIcon(item, $event)">
              <div class="icon-item">
                <svg-icon :icon-class="item" class-name="disabled" />
                <span>{{ item }}</span>
              </div>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="Element-UI Icons">
          <div class="grid">
            <div v-for="item of elementIcons" :key="item" @click="handleCheckIcon(generateElementIconCode(item), $event)">
              <div class="icon-item">
                <i :class="'el-icon-' + item" />
                <span>{{ item }}</span>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>
</template>

<script>
import { menuTree, createMenu, updateMenu, deleteMenu } from '@/api/menu'
import { allRoles } from '@/api/role'

import svgIcons from '@/utils/svg-icons'
import elementIcons from '@/utils/element-icons'

export default {
  name: 'MenuList',

  data() {
    const validatePid = (rule, value, callback) => {
      if (this.dialogStatus === 'update' && value === this.temp.id) {
        callback(new Error('父级菜单不能跟当前菜单相同'))
      } else {
        callback()
      }
    }
    return {
      listLoading: true,
      svgIcons,
      elementIcons,
      list: [],
      dialogFormVisible: false,
      dialogIconVisible: false,
      dialogStatus: '',
      dialogTitleMap: {
        update: '编辑',
        create: '创建'
      },
      search: '',
      temp: {
        id: 0,
        pid: 0,
        title: '',
        hidden: 0,
        breadcrumb: 1,
        icon: '',
        path: '',
        redirect: '',
        sort: 0,
        roles: [],
        no_cache: 0,
        affix: 0
      },
      roleList: [],
      rules: {
        title: [
          { required: true, message: '请输入菜单名称', trigger: ['blur', 'change'] },
          { min: 2, message: '菜单名称不能少于2位', trigger: ['blur', 'change'] },
          { max: 30, message: '菜单名称不能大于30位', trigger: ['blur', 'change'] }
        ],
        pid: [{ validator: validatePid, trigger: ['blur', 'change'] }],
        path: [
          { required: true, message: '请输入前端路由路径', trigger: ['blur', 'change'] },
          { min: 2, message: '前端路由路径不能少于2位', trigger: ['blur', 'change'] },
          { max: 100, message: '前端路由路径不能大于100位', trigger: ['blur', 'change'] }
        ],
        name: [
          { required: true, message: '请输入前端路由名称', trigger: ['blur', 'change'] },
          { min: 2, message: '前端路由名称不能少于2位', trigger: ['blur', 'change'] },
          { max: 100, message: '前端路由名称不能大于40位', trigger: ['blur', 'change'] }
        ],
        redirect: [
          { min: 2, message: '前端路由重定向不能少于2位', trigger: ['blur', 'change'] },
          { max: 100, message: '前端路由重定向不能大于100位', trigger: ['blur', 'change'] }
        ],
        sort: [{ required: true, message: '请输入排序', trigger: ['blur', 'change'] }, { type: 'integer', message: '排序必须是数字', trigger: ['blur', 'change'] }]
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    resetTemp() {
      this.temp = {
        id: 0,
        pid: 0,
        title: '',
        hidden: 0,
        breadcrumb: 1,
        icon: '',
        path: '',
        redirect: '',
        sort: 0,
        roles: [],
        no_cache: 0,
        affix: 0
      }
    },
    generateElementIconCode(symbol) {
      return `el-icon-${symbol}`
    },
    handleCheckIcon(text, event) {
      this.temp.icon = text
      this.dialogIconVisible = false
    },
    getList() {
      this.listLoading = true
      menuTree(this.searchFilter).then(response => {
        this.list = response.data.list
        this.listLoading = false
      })
    },
    getAllRoles() {
      allRoles().then(res => {
        this.roleList = res.data.list
        this.dialogFormVisible = true
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
        })
      })
    },
    handleCreate() {
      this.resetTemp()
      this.dialogStatus = 'create'
      this.getAllRoles()
    },
    handleUpdate(row) {
      this.temp = Object.assign({}, row)
      this.dialogStatus = 'update'
      this.getAllRoles()
    },
    handleSwitch(row) {
      this.temp = { ...this.temp, ...row }
      updateMenu(this.temp).then(res => {
        this.getList()
        this.$notify({
          title: '成功',
          message: res.message,
          type: 'success',
          duration: 2000
        })
      })
    },
    handleDelete(row) {
      this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteMenu(row).then(res => {
          const index = this.list.findIndex(v => v.id === row.id)
          this.list.splice(index, 1)
          this.$notify({
            title: '成功',
            message: res.message,
            type: 'success',
            duration: 2000
          })
        })
      })
    },
    createData() {
      this.$refs['dataForm'].validate(valid => {
        if (valid) {
          createMenu(this.temp).then(res => {
            this.getList()
            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: res.message,
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },
    updateData() {
      this.$refs['dataForm'].validate(valid => {
        if (valid) {
          updateMenu(this.temp).then(res => {
            this.getList()
            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: res.message,
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    }
  }
}
</script>

<style scoped="scoped">
.action-container {
  margin-bottom: 15px;
}

.iconDialog .grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.iconDialog .icon-item {
  margin: 20px;
  height: 85px;
  text-align: center;
  width: 100px;
  float: left;
  font-size: 30px;
  color: #24292e;
  cursor: pointer;
}

.iconDialog span {
  display: block;
  font-size: 16px;
  margin-top: 10px;
}

.iconDialog .disabled {
  pointer-events: none;
}

.select-icon-btn {
  cursor: pointer !important;
}
</style>
